from tortoise.models import Model
from tortoise import fields
from tortoise.contrib.postgres.fields import ArrayField
from enum import Enum
from datetime import datetime
import json


# 枚举类型定义
class UserType(str, Enum):
    NORMAL = "normal"  # 普通用户
    VIP = "vip"  # VIP用户
    SVIP = "svip"  # 超级VIP用户


class UserStatus(str, Enum):
    ACTIVE = "active"  # 活跃
    INACTIVE = "inactive"  # 不活跃
    BANNED = "banned"  # 封禁


class PlatformType(str, Enum):
    QQ = "qq"  # QQ登录
    GITEE = "gitee"  # Gitee登录
    WECHAT = "wechat"  # 微信登录
    DINGDING = "dingding"  # 钉钉登录


class CategoryType(str, Enum):
    HOT = "hot"  # 热门
    OUTDOOR = "outdoor"  # 户外
    SCENIC = "scenic"  # 景点
    MOUNTAIN = "mountain"  # 山川
    ISLAND = "island"  # 岛屿
    CITYWALK = "citywalk"  # 城市漫步


class LocationType(str, Enum):
    ATTRACTION = "attraction"  # 景点
    FOOD = "food"  # 美食
    NIGHTLIFE = "nightlife"  # 夜生活
    CAMPUS = "campus"  # 校园
    FAMILY = "family"  # 家庭
    SHOPPING = "shopping"  # 购物


class LiveCategoryType(str, Enum):
    HONGKONG_MACAO_TAIWAN = "hongkong_macao_taiwan"  # 港澳台
    PROVINCE = "province"  # 省份
    CONTINENT = "continent"  # 大洲
    RECOMMEND = "recommend"  # 推荐
    DOMESTIC = "domestic"  # 国内
    LOCATION = "location"  # 地点
    INTERNATIONAL = "international"  # 国际


class StreamStatus(str, Enum):
    LIVE = "live"  # 直播中
    ENDED = "ended"  # 已结束
    SCHEDULED = "scheduled"  # 已预约


class PaceType(str, Enum):
    RELAXED = "relaxed"  # 轻松
    MODERATE = "moderate"  # 适中
    INTENSIVE = "intensive"  # 紧凑


class BudgetType(str, Enum):
    BUDGET = "budget"  # 经济
    MODERATE = "moderate"  # 适中
    LUXURY = "luxury"  # 豪华


class SearchType(str, Enum):
    MAP = "map"  # 地图搜索
    TOPIC = "topic"  # 主题搜索
    GENERAL = "general"  # 普通搜索


class LocationSearchType(str, Enum):
    ALL = "all"  # 全部
    ATTRACTION = "attraction"  # 景点
    FOOD = "food"  # 美食
    NIGHTLIFE = "nightlife"  # 夜生活
    CAMPUS = "campus"  # 校园
    FAMILY = "family"  # 家庭


# JSON字段编码器
class JSONField(fields.JSONField):
    def to_db_value(self, value, instance):
        if value is None:
            return None
        return json.dumps(value, ensure_ascii=False)

    def to_python_value(self, value):
        if value is None:
            return None
        if isinstance(value, str):
            return json.loads(value)
        return value


# 1. 用户表
class User(Model):
    id = fields.IntField(pk=True, description='用户ID')
    username = fields.CharField(max_length=50, unique=True, description='用户名')
    email = fields.CharField(max_length=100, unique=True, null=True, description='邮箱')
    phone = fields.CharField(max_length=20, null=True, description='手机号')
    password_hash = fields.CharField(max_length=255, description='密码哈希值')
    avatar = fields.CharField(max_length=255, null=True, description='头像URL')
    nickname = fields.CharField(max_length=50, null=True, description='昵称')
    bio = fields.TextField(null=True, description='个人简介')
    user_type = fields.CharEnumField(UserType, default=UserType.NORMAL, description='用户类型')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')
    last_login_at = fields.DatetimeField(null=True, description='最后登录时间')
    status = fields.CharEnumField(UserStatus, default=UserStatus.ACTIVE, description='用户状态')

    class Meta:
        table = "users"
        table_description = "用户表"

    def __str__(self):
        return f"User({self.username})"


# 2. 第三方登录表
class ThirdPartyLogin(Model):
    id = fields.IntField(pk=True, description='第三方登录ID')
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="third_party_logins", on_delete=fields.CASCADE, description='用户ID'
    )
    platform = fields.CharEnumField(PlatformType, description='平台类型')
    open_id = fields.CharField(max_length=255, description='开放ID')
    union_id = fields.CharField(max_length=255, null=True, description='联合ID')
    access_token = fields.CharField(max_length=255, null=True, description='访问令牌')
    refresh_token = fields.CharField(max_length=255, null=True, description='刷新令牌')
    expires_at = fields.DatetimeField(null=True, description='过期时间')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "third_party_logins"
        table_description = "第三方登录表"

    def __str__(self):
        return f"ThirdPartyLogin({self.user_id}-{self.platform})"


# 3. 分类表
class Category(Model):
    id = fields.IntField(pk=True, description='分类ID')
    name = fields.CharField(max_length=50, description='分类名称')
    type = fields.CharEnumField(CategoryType, description='分类类型')
    parent: fields.ForeignKeyRelation['Category'] = fields.ForeignKeyField(
        "models.Category", related_name="children", null=True, on_delete=fields.SET_NULL, description='父分类ID'
    )
    sort_order = fields.IntField(default=0, description='排序顺序')
    icon = fields.CharField(max_length=255, null=True, description='图标URL')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "categories"
        table_description = "分类表"

    def __str__(self):
        return f"Category({self.name})"


# 4. 地点表
class Location(Model):
    id = fields.IntField(pk=True, description='地点ID')
    name = fields.CharField(max_length=100, description='地点名称')
    type = fields.CharEnumField(LocationType, description='地点类型')
    category: fields.ForeignKeyRelation[Category] = fields.ForeignKeyField(
        "models.Category", related_name="locations", null=True, on_delete=fields.SET_NULL, description='分类ID'
    )
    latitude = fields.DecimalField(max_digits=10, decimal_places=8, null=True, description='纬度')
    longitude = fields.DecimalField(max_digits=11, decimal_places=8, null=True, description='经度')
    address = fields.CharField(max_length=255, null=True, description='详细地址')
    city = fields.CharField(max_length=50, null=True, description='城市')
    province = fields.CharField(max_length=50, null=True, description='省份')
    country = fields.CharField(max_length=50, default="中国", description='国家')
    description = fields.TextField(null=True, description='地点描述')
    images = JSONField(null=True, description='图片列表')
    rating = fields.DecimalField(max_digits=3, decimal_places=2, default=0.00, description='评分')
    price_level = fields.IntField(default=0, description='价格等级')
    opening_hours = fields.TextField(null=True, description='开放时间')
    contact_phone = fields.CharField(max_length=20, null=True, description='联系电话')
    website = fields.CharField(max_length=255, null=True, description='官方网站')
    tags = JSONField(null=True, description='标签列表')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')
    status = fields.CharField(max_length=10, default='active', description='状态')

    class Meta:
        table = "locations"
        table_description = "地点表"

    def __str__(self):
        return f"Location({self.name})"


# 5. 直播分类表
class LiveCategory(Model):
    id = fields.IntField(pk=True, description='直播分类ID')
    name = fields.CharField(max_length=50, description='分类名称')
    type = fields.CharEnumField(LiveCategoryType, description='分类类型')
    sort_order = fields.IntField(default=0, description='排序顺序')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "live_categories"
        table_description = "直播分类表"

    def __str__(self):
        return f"LiveCategory({self.name})"


# 6. 直播表
class LiveStream(Model):
    id = fields.IntField(pk=True, description='直播ID')
    title = fields.CharField(max_length=200, description='直播标题')
    description = fields.TextField(null=True, description='直播描述')
    streamer: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="live_streams", on_delete=fields.CASCADE, description='主播ID'
    )
    category: fields.ForeignKeyRelation[LiveCategory] = fields.ForeignKeyField(
        "models.LiveCategory", related_name="live_streams", null=True, on_delete=fields.SET_NULL, description='分类ID'
    )
    cover_image = fields.CharField(max_length=255, null=True, description='封面图片')
    stream_url = fields.CharField(max_length=500, description='直播流地址')
    status = fields.CharEnumField(StreamStatus, default=StreamStatus.SCHEDULED, description='直播状态')
    viewer_count = fields.IntField(default=0, description='观看人数')
    start_time = fields.DatetimeField(null=True, description='开始时间')
    end_time = fields.DatetimeField(null=True, description='结束时间')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "live_streams"
        table_description = "直播表"

    def __str__(self):
        return f"LiveStream({self.title})"


# 7. 行程表
class Itinerary(Model):
    id = fields.IntField(pk=True, description='行程ID')
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="itineraries", on_delete=fields.CASCADE, description='用户ID'
    )
    title = fields.CharField(max_length=200, description='行程标题')
    description = fields.TextField(null=True, description='行程描述')
    travel_reason = fields.TextField(null=True, description='出行理由')
    start_date = fields.DateField(null=True, description='开始日期')
    end_date = fields.DateField(null=True, description='结束日期')
    travel_days = fields.IntField(default=1, description='旅行天数')
    pace = fields.CharEnumField(PaceType, default=PaceType.MODERATE, description='行程节奏')
    budget_type = fields.CharEnumField(BudgetType, default=BudgetType.MODERATE, description='预算类型')
    preference_tags = JSONField(null=True, description='偏好标签')
    is_public = fields.BooleanField(default=False, description='是否公开')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')
    updated_at = fields.DatetimeField(auto_now=True, description='更新时间')

    class Meta:
        table = "itineraries"
        table_description = "行程表"

    def __str__(self):
        return f"Itinerary({self.title})"


# 8. 行程地点关联表
class ItineraryLocation(Model):
    id = fields.IntField(pk=True, description='行程地点ID')
    itinerary: fields.ForeignKeyRelation[Itinerary] = fields.ForeignKeyField(
        "models.Itinerary", related_name="itinerary_locations", on_delete=fields.CASCADE, description='行程ID'
    )
    location: fields.ForeignKeyRelation[Location] = fields.ForeignKeyField(
        "models.Location", related_name="itinerary_locations", on_delete=fields.CASCADE, description='地点ID'
    )
    day_number = fields.IntField(description='第几天')
    sort_order = fields.IntField(default=0, description='排序顺序')
    visit_duration = fields.IntField(null=True, description='参观时长(分钟)')
    notes = fields.TextField(null=True, description='备注')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "itinerary_locations"
        table_description = "行程地点关联表"

    def __str__(self):
        return f"ItineraryLocation({self.itinerary_id}-{self.location_id})"


# 9. 心愿单表
class Wishlist(Model):
    id = fields.IntField(pk=True, description='心愿单ID')
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="wishlists", on_delete=fields.CASCADE, description='用户ID'
    )
    location: fields.ForeignKeyRelation[Location] = fields.ForeignKeyField(
        "models.Location", related_name="wishlists", on_delete=fields.CASCADE, description='地点ID'
    )
    notes = fields.TextField(null=True, description='备注')
    priority = fields.IntField(default=1, description='优先级')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "wishlists"
        table_description = "心愿单表"

    def __str__(self):
        return f"Wishlist({self.user_id}-{self.location_id})"


# 10. 搜索记录表
class SearchRecord(Model):
    id = fields.IntField(pk=True, description='搜索记录ID')
    user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField(
        "models.User", related_name="search_records", null=True, on_delete=fields.SET_NULL, description='用户ID'
    )
    keyword = fields.CharField(max_length=100, description='搜索关键词')
    search_type = fields.CharEnumField(SearchType, default=SearchType.GENERAL, description='搜索类型')
    location_type = fields.CharEnumField(LocationSearchType, default=LocationSearchType.ALL, description='地点类型')
    latitude = fields.DecimalField(max_digits=10, decimal_places=8, null=True, description='纬度')
    longitude = fields.DecimalField(max_digits=11, decimal_places=8, null=True, description='经度')
    search_results_count = fields.IntField(default=0, description='搜索结果数量')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "search_records"
        table_description = "搜索记录表"

    def __str__(self):
        return f"SearchRecord({self.keyword})"


# 11. 热门行程参考表
class PopularItinerary(Model):
    id = fields.IntField(pk=True, description='热门行程ID')
    title = fields.CharField(max_length=200, description='行程标题')
    description = fields.TextField(null=True, description='行程描述')
    travel_days = fields.IntField(description='旅行天数')
    pace = fields.CharEnumField(PaceType, default=PaceType.MODERATE, description='行程节奏')
    budget_type = fields.CharEnumField(BudgetType, default=BudgetType.MODERATE, description='预算类型')
    tags = JSONField(null=True, description='标签')
    view_count = fields.IntField(default=0, description='浏览数')
    like_count = fields.IntField(default=0, description='点赞数')
    is_active = fields.BooleanField(default=True, description='是否激活')
    created_at = fields.DatetimeField(auto_now_add=True, description='创建时间')

    class Meta:
        table = "popular_itineraries"
        table_description = "热门行程参考表"

    def __str__(self):
        return f"PopularItinerary({self.title})"
